function unFreeze() {
    importClass(com.stardust.autojs.core.accessibility.AccessibilityBridge.WindowFilter);
    let bridge = runtime.accessibilityBridge;
    let bridgeField = runtime.getClass().getDeclaredField("accessibilityBridge");
    let configField = bridgeField.getType().getDeclaredField("mConfig");
    configField.setAccessible(true);
    configField.set(bridge, configField.getType().newInstance());
    bridge.setWindowFilter(new JavaAdapter(AccessibilityBridge$WindowFilter, {
        filter: function (info) {
            return true;
        }
    }));
}

function checkSignResult(type) {
    // 检查打卡结果
    if (type == "on") {
        var workTag1 = text("下班打卡").exists()
        var workTag2 = text("补卡申请").exists()
        return workTag1 || workTag2
    } else {
        var freeTag = text("补卡申请").exists()
        return freeTag
    }
}

function autoSign(type) {
    // 上下班打卡
    let signResult = checkSignResult(type)
    if (signResult) {
        console.log("卡已经打过，重复打卡无效");
        return true
    }
    let widgetInfo = "上班打卡";
    if (type === "off") {
        widgetInfo = "下班打卡";
    }
    sleep(1000);
    var signButton = className("android.widget.TextView").text(widgetInfo);
    // signButton.waitFor()
    for (var k = 0; k < 3; k++) {
        if(signButton.exists()){
            signButton.findOne(5000).parent().click();
            break;
        }
        console.info("第：", k+1, "次点击[", widgetInfo, "]失败")
        sleep(2000);
    }
    
    for (n = 0; n < 3; n++) {
        if(text("确认打卡").exists()){
            break
        }
        console.info("第：", k+1, "次寻找[确认打卡]控件失败")
        sleep(2000);
    }
    
    if (text("拍照上传水印图片作为辅助证明").findOnce().checked()) {  // 不上传水印照片作为辅助证明
        text("拍照上传水印图片作为辅助证明").findOnce().click()
    }
    sleep(1000);
    text("确认打卡").findOnce().click();
    console.log("打卡完成...");
    return true
}

function enterWorkPlantform() {
    // 进入工作台界面
    let initialControlsNumber = text("工作台").find().length
    if (text("工作台").find().get(initialControlsNumber - 1).selected()) {
        // 如果当前在工作台tab页，就直接进行打卡操作
        console.log("当前已处在工作台标签页")
        sleep(1000);
        return true
    } else {
        // 尝试三次点击工作台
        let currentControlsNumber = text("工作台").find().length
        for (var i = 0; i < 3; i++) {
            // 严重强调：（测试时autojs尽量保持非稳定模式，因为打包apk是非稳定模式）
            // 当不打包apk时，此处工作台文本控件的父控件就可以点击
            // let wbutton = text("工作台").find().get(currentControlsNumber - 1).parent()
            // 当打包后，工作台文本控件的父控件的父控件才可以点击
            let wsbutton = text("工作台").find().get(currentControlsNumber - 1).parent().parent()
            if (wsbutton.clickable()) {
                wsbutton.click()
            } else {
                console.info($util.format("第：%d 次找到的工作控件不可点击.", i+1))
                console.log(wsbutton)
                continue
            }
            sleep(300)
            // 为何此处不直接使用workPlantform.selected()判断？
            // 因为workPlantform在获取之初其属性就已经确定，不会随者元素点击而改变，所以需要重新获取
            
            // 此处为何重新获取工作台文本长度
            // 1.情况一：当不处于工作台界面时，工作台文本选择器只能选择到一个控件
            // 2.情况二：当处于工作台界面时，可能存在两个或三个控件
            // 所以如果处于其他tab界面，那么在点击后会进入到工作台界面，此时工作台文本控件数量会变化，如果还是使用最初的totalNum，那么就会出现获取的控件对象，不一定是我们真实想要的
            let currentTotalNum = text("工作台").find().length  
            if (text("工作台").find().get(currentTotalNum - 1).selected()) {
                console.log("进入工作台成功")
                return true
            } else {
                // 测试过程中，如果点击了工作台父控件，那么工作台文本控件会被选中，即：selected() 为 true
                console.log("点击了工作台父控件，但是工作台文本控件未被选中")
                console.log(text("工作台").find().get(currentTotalNum - 1))
            }
            console.info($util.format("第：%d 次点击工作台失败.", i+1))
        }
        // 如果三次元素点击都未成功,则尝试一次使用坐标点击
        console.info("最后再尝试使用坐标点击工作台一次.")
        let totalControlsNumber = text("工作台").find().length
        let button = text("工作台").find().get(totalControlsNumber - 1).parent().bounds()
        click(button.centerX(), button.centerY())
        sleep(200)
        if (text("工作台").find().get(totalControlsNumber - 1).selected()) {
            console.log("通过坐标点击进入工作台成功")
            return true
        }
        console.error("进入工作台失败");
        return false
    }
}

function clickSign() {
    // 进入打卡界面
    var target = text("打卡").findOnce();
    if (target) {
        var clickSignButton = false;
        // 尝试3次
        for (var j = 0; j < 3; j++) {
            if (text("打卡").findOne(3000).parent().clickable()) {
                text("打卡").findOne(3000).parent().click()
            } else {
                var region = text("打卡").findOne(3000).parent().bounds();
                click(region.centerX(), region.centerY());
            }
            sleep(1000);
            if(text("补卡申请").exists() || text("上班打卡").exists() || text("下班打卡").exists()){
                clickSignButton = true;
                break;
            }
            console.info($util.format("第：%d 次进入打卡界面失败.", j+1))
            sleep(800); 
        }
        if (!clickSignButton) {
            console.info("最后再尝一次，试使用坐标位置点击进入打卡界面.")
            let button = text("打卡").findOne(3000).parent().bounds()
            click(button.centerX(), button.centerY())
            sleep(1000);
            if(text("补卡申请").exists() || text("上班打卡").exists() || text("下班打卡").exists()){
                console.log("通过坐标点击进入打卡界面成功")
                return true
            }
            console.error("点击打卡控件失败");
            return false
        }
        return true;
    } else {
        console.error("未找到打卡文本控件")
        return false
    }
}

function enterSign() {
    /*
    情况1：
        进入软件后，直接弹出立即打卡
    情况2：
        需要一步一步操做，先点击工作台，再点击打卡
    */
    // 1.如果有立即打卡的弹窗则点击立即打卡
    if(text("立即打卡").exists()){
        text("立即打卡").findOne().click();
        sleep(2000);
        if(text("上班打卡").exists() || text("下班打卡").exists()){
            console.log("通过立即打进入打卡界面成功");
            sleep(1000);
            return true;
        } else {
            console.error("通过立即打卡进入打卡界面失败")
            return false
        }
    } else {
        // 首先需要处于主界面，否则不能找到工作台
        var start = new Date().getTime();
        while (true) {
            email = className("android.widget.TextView").text("邮件").exists()
            work = className("android.widget.TextView").text("工作台").exists()
            isMainInterface = email && work
            if (!isMainInterface) {
                back()
            } else {
                break
            }
            // 设置超时退出循环，避免死循环出现
            var end = new Date().getTime();
            if (end - start > 10000) {
                throw "未能回到主界面去点击工作台"
            }
            sleep(300)
        }
        // 2.需要一步一步操做：先尝试3轮进入工作台
        for (var k = 1; k < 4; k++) {
            console.info($util.format("第：%d 轮尝试进入工作台.", k))
            try{
                var clickWorkPlatformResult = enterWorkPlantform();
            } catch (error) {
                console.error($util.format("第：%d 轮尝试进入工作台失败：%s", k, error))
                continue
            }
            if (clickWorkPlatformResult) {
                break;
            }
            sleep(800);
        };
        
        if (clickWorkPlatformResult) {
            // 如果进入工作台成功，再尝试3次点击进入打卡界面
            for (var l = 1; l < 4; l++) {
                console.info($util.format("第：%d 轮尝试进入打卡界面.", l))
                try {
                    var clickSignCardResult = clickSign();
                    if (clickSignCardResult) {
                        break
                    }
                }catch (error) {
                    console.error($util.format("第：%d 轮尝试进入打卡界面失败：%s", l, error))
                    continue
                }
            }
            
            if (clickSignCardResult) {
                sleep(3000);
                console.info("通过工作台进入打卡界面成功")
                return true
            } else {
                console.error("通过工作台进入打卡界面失败")
                return false
            }
        } else {
            console.error("进入工作台失败")
            return false
        }
    }
}

function login(){
    // Auto.js解除限制
    unFreeze();
    // 判断是否有隐私保护指引，如果有，点击同意
    if (text("同意").exists()) {
        text("同意").click()
    }
    // 使用微信登录
    if(text("微信登录").exists()){
        console.log("开始使用微信登录");
        // 勾选协议
        var protocolUiObj = id("com.tencent.wework:id/nc").findOnce();
        if (!protocolUiObj.selected()) {
            protocolUiObj.click();
        }
        sleep(500);
        text("微信登录").click()
        sleep(300)
        // 如果微信多开，则默认使用左边第一个登录
        if (text("微信").exists()) {
            text("微信").find().get(0).parent().click()
        }
        sleep(3000);
        if (text("进入").exists()) {
            console.log("有登录缓存，直接进入企业微信...")
            text("进入").findOnce().click()
            sleep(2000);
        } else if (text("允许").exists()) {
            console.log("微信三方登录中...")
            sleep(2000);
            text("允许").click();
            sleep(2000);
            text("允许").click();
            sleep(1000);
            if (text("进入").exists()) {
                console.log("完成登录，准备进入企业微信...")
                text("进入").findOnce().click()
                sleep(2000);
            }
        }
    } else {
        console.log("企业微信登录状态正常")
        return true
    }
}

console.show();
var qywx = {};
qywx.run = function main(type){  
    try {
        console.log("正在打开企业微信...");
        // 打开企业微信应用
        app.launch("com.tencent.wework");
        waitForPackage("com.tencent.wework", 5000);
        sleep(2000);
        console.log("打开企业微信成功...");
    } catch (error) {
        console.error("打开企业微信失败：",  error);
        console.hide();
        throw error
    }

    try {
        // 判断登录情况
        login();
        sleep(2000);
    } catch (error) {
        console.error("登录企业微信失败：",  error);
        console.hide();
        throw error
    }

    try {
        // 进入打卡界面
        let resilt = enterSign()
        if (!resilt) {
            throw "进入打卡界面失败"
        }
        console.log("进入打卡界面结果：", resilt)
    } catch (error) {
        console.error("进入打卡界面失败：",  error);
        console.hide();
        throw error
    }

    // 尝试打卡三次
    for (let index = 0; index < 3; index++) {
        console.log("开始打卡...")
        try {
            var result = autoSign(type)
            sleep(2000);
            if (result) {
                sleep(2000);
                break;
            }
        } catch (error) {
            console.error($util.format("第：%d 次打卡失败: %s", index+1, error));
            continue
        }
    }

    // 打卡结果查询
    var result = checkSignResult(type)
    if (result) {
        console.log("打卡成功...");
    } else {
        console.error("打卡失败...");
    }
    sleep(1000);

    // 如果原本是锁屏的，打卡完成后，继续锁屏
    // if (lockedFlag) {
    //     // 需要root权限
    //     devicePolicyManager.lockNow();
    // }

    // 返回主菜单，关闭悬浮日志框，然后退出程序
    back();
    sleep(600);
    home();
}
module.exports = qywx;
